<?php

use Yaf\Request_Abstract as Request;
use Yaf\Response_Abstract as Response;
use Lib\Stats;

class AdmittancePlugin extends \Yaf\Plugin_Abstract {

    protected $request = null;

    public function routerShutdown(Request $request, Response $response) {
        $this->request = $request;
        Stats::connect();

        $this->ignoreSignature() === false && $this->verifiySignature();
        $this->verifiyToken();
        Stats::request();
    }

    /**
     * 签名校验
     *
     * @throws \Exception
     */
    private function verifiySignature() {
        $request   = $this->request;
        $signature = (string)$request->get('signature');

        if((int)$request->get('disable_signature', 0) === 1) {
            return true;
        }

        $pubKey = trim($request->getServer('HTTP_API_PUBKEY'));

        if(!empty($signature) && !empty($pubKey)) {
            $priKeys = $this->getConfig()->get('resources.api.prikeys');

            if(!empty($priKeys[$pubKey])) {
                $params = array_merge((array)$request->getPost(), (array)$request->getQuery());

                unset($params['signature']);
                ksort($params);

                $origin = $pubKey;

                foreach ($params as $key => $val) {
                    $origin .= sprintf('%s=%s', $key, urlencode($val));
                }

                $origin .= $priKeys[$pubKey];

                if(strcasecmp($signature, md5($origin)) === 0) {
                    return true;
                }
            }
        }

        throw new \Exception("invalid signature", 90101);
    }

    /**
     * 校验Token
     *
     * @return boolean
     */
    private function verifiyToken() {
        $request = $this->request;
        $token   = trim($request->getServer('HTTP_API_TOKEN'));

        if(!empty($token)) {
            $tokenCls = \Lib\Token::getInstance();

            if($tokenCls->valid($token) === true) {
                $uid = $tokenCls->getStd()->getUid();

                \Lib\User::getInstance()->valid($uid);

                return true;
            }
        }

        return false;
    }

    /**
     * 忽略签名校验
     *
     * @return boolean
     */
    private function ignoreSignature() {
        $ignores = $this->getConfig()->get('resources.ignore.signature');
        $ignored = false;

        if($ignores instanceof \Yaf\Config\Ini) {
            $ignoreArr = $ignores->toArray();

            if(!is_array($ignoreArr) || empty($ignoreArr)) {
                return $ignored;
            }

            $request    = $this->request;
            $module     = $request->getModuleName();
            $controller = $request->getControllerName();
            $action     = $request->getActionName();
            $ruleC      = sprintf('%s.*.*', $module);
            $ruleB      = sprintf('%s.%s.*', $module, $controller);
            $ruleA      = sprintf('%s.%s.%s', $module, $controller, $action);

            sort($ignoreArr);

            foreach ($ignoreArr as $ignore) {
                if(strcasecmp($ignore, '*') === 0
                    || strcasecmp($ignore, $ruleC) === 0
                    || strcasecmp($ignore, $ruleB) === 0
                    || strcasecmp($ignore, $ruleA) === 0
                ) {
                    $ignored = true;
                    break;
                }
            }
        }

        return $ignored;
    }

    /**
     * 配置
     *
     * @return \Yaf\Config\Ini
     */
    private function getConfig() {
        return \Yaf\Application::app()->getConfig();
    }
}

